//
//  XLGDownloadHttpOperation.m
//  etionLib
//
//  Created by JingXing Wu on 12-5-12.
//  Copyright (c) 2012年 GuangZhouXuanWu. All rights reserved.
//

#import "XLGDownloadHttpOperation.h"

#import "XLGDownloadOperation+XLGDownloadOperationInternal.h"

#import "RequestChannelPool.h"

@implementation XLGHttpDownloadOperationCore

@synthesize URLConnection = _URLConnection;

-(BOOL)terminateSelfRequest:(BOOL)bRejectrequest
{
    [_URLConnection cancel];
    
    return YES;
}

-(void)dealloc
{
    [_URLConnection release_mm];
    superdealloc_mm;
}

@end

@implementation XLGDownloadHttpOperation
{
    NSString *_eTagPath;
}

-(void)dealloc
{
    [_eTagPath release_mm];
    superdealloc_mm;
}

-(XLGDownloadOperationCore*)createDownloadOperationCore
{
    return [[XLGHttpDownloadOperationCore new]autorelease_mm];
}

-(XLGHttpDownloadOperationCore*)core
{
    return (XLGHttpDownloadOperationCore*)super.core;
}

-(BOOL)startItem
{
    [super startItem];
    
    NSString *URLString = _mi.URL;
    if(s_transferURL != NULL)
        URLString = s_transferURL(URLString);
    
    _eTagPath = [[[_filePath stringByDeletingPathExtension] stringByAppendingPathExtension:@"etag"] retain_mm];
    
    NSURL *url = [NSURL URLWithString:[URLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:20];
    [theRequest setValue:[NSString stringWithFormat:@"bytes=%@-",@(_fileCurrentSize)] forHTTPHeaderField:@"Range"];
    
    if(_fileCurrentSize > 0)
    {
        NSString *s = [NSString stringWithContentsOfFile:_eTagPath encoding:NSUTF8StringEncoding error:nil];
        if(s.length > 0)
            [theRequest setValue:s forHTTPHeaderField:@"If-Range"];
    }
    
    [CRequestChannelPoolShell addRequestChannel:^CRequestChannel *
    {
        return self.core;
    }];
    BOOL bResult = NO;
    if(self.core !=nil)
    {
        bResult = [self.core.channelPool addRequestChannelPoolRunLoop:^(NSRunLoop *runloop)
        {
            self.core.URLConnection = [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:NO] autorelease_mm];
            [self.core.URLConnection scheduleInRunLoop:runloop forMode:NSDefaultRunLoopMode];
            [self.core.URLConnection start];
        }];
    }
    if(bResult != YES)
    {
#ifdef DEBUG
        NSLog(@"HTTP下载启动失败");
#endif
    }
    
    return bResult;
}

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)aResponse
{
	NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)aResponse;
    
    NSString *eTag = [httpResponse allHeaderFields][@"ETag"];
    if(eTag.length > 0)
    {
        [eTag writeToFile:_eTagPath atomically:NO encoding:NSUTF8StringEncoding error:nil];
    }
	
	NSInteger nErrorcode=[httpResponse statusCode];
    
    if(2 == nErrorcode / 100)
    {
        _fileTotalSize = [httpResponse expectedContentLength];
        
        if(_fileTotalSize <= 0)
        {
            if(_mi.totalByte > 0)
                _fileTotalSize = _mi.totalByte;
            else
                _fileTotalSize = NSNotFound;
        }
        
        [self initFileData];
    }
    else
    {
        [super downloadError];
    }
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
    [self writeDataToFile:theData];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [super downloadFinished];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [super downloadError];
}

-(BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection
{
    return YES;
}

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        [[challenge sender] useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    }
}

-(void)cleanup
{
    [self.core terminateRequest];
    [self.core.channelPool removeRequestChannelPoolRunLoop:^(NSRunLoop *runloop)
    {
        [self.core.URLConnection unscheduleFromRunLoop:runloop forMode:NSDefaultRunLoopMode];
    }];
    [CRequestChannelPoolShell removeRequestChannel:^CRequestChannel *
    {
        return self.core;
    }];
    [super cleanup];
}

-(void)stopDownload
{
    [super stopDownload];
    
	[self cleanup];
}

+(void)operateNeedTransferURLBlock:(NSString*(^)(NSString *URL))transferURL
{
    if(s_transferURL != NULL)
        Block_release(s_transferURL);
    s_transferURL = NULL;
    if(transferURL != NULL)
        s_transferURL = Block_copy(transferURL);
}

@end
